package org.eureka.manager.web;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用于心跳检测
 */
@RestController
@Slf4j
@RequestMapping("health")
@ConditionalOnWebApplication(
        type = ConditionalOnWebApplication.Type.SERVLET
)
public class HealthCheckServletController {

    @GetMapping(value = "check")
    public void isRunning(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.debug("=================healthcheck is running=====================check client ip:{}", getIpByRequest(request));
        response.getWriter().println("OK");
        response.getWriter().flush();
    }


    private static final String UNKOWN = "unkown";

    private static final String LOOP_IP = "127.0.0.1";

    private static final int IP_SPLIT_LENGTH = 4;

    public static String getIpByRequest(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("x-forwarded-for");
        String ip = null;
        if (xForwardedFor != null) {
            ip = xForwardedFor.split(",")[0];
            if (isIpValid(ip)) {
                log.info("get ip xForwardedFor，ip={}", ip);
                return ip;
            }
        }

        ip = request.getHeader("X-Real-IP");
        if (isIpValid(ip)) {
            log.info("get ip X-Real-IP，ip={}", ip);
            return ip;
        }

        ip = request.getHeader("Proxy-Client-IP");
        if (isIpValid(ip)) {
            log.info("get ip Proxy-Client-IP，ip={}", ip);
            return ip;
        }
        ip = request.getHeader("WL-Proxy-Client-IP");
        if (isIpValid(ip)) {
            log.info("get ip WL-Proxy-Client-IP，ip={}", ip);
            return ip;
        }
        ip = request.getRemoteAddr();
        if (isIpValid(ip)) {
            log.info("get ip from remote addr，ip={}", ip);
            return ip;
        }
        log.info("get ip fail");
        return LOOP_IP;
    }


    private static boolean isIpValid(String ip) {
        if (StringUtils.isBlank(ip) || UNKOWN.equalsIgnoreCase(ip) || ip.split("\\.").length != IP_SPLIT_LENGTH) {
            return false;
        }
        return true;
    }
}